/*
 * Copyright 2017 Baiyyy
 * @(#)WarningServiceImpl.java
 */

package com.byyy.ccts.modules.cc.service.impl;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.byyy.ccts.core.base.ILogBase;
import com.byyy.ccts.core.common.service.impl.CommonServiceImpl;
import com.byyy.ccts.core.message.rocketmq.OAProducer;
import com.byyy.ccts.core.query.data.Page;
import com.byyy.ccts.core.query.data.PageImpl;
import com.byyy.ccts.core.query.data.Pageable;
import com.byyy.ccts.core.query.data.Queryable;
import com.byyy.ccts.core.query.parse.QueryToWrapper;
import com.byyy.ccts.core.query.wrapper.EntityWrapper;
import com.byyy.ccts.core.utils.DateUtils;
import com.byyy.ccts.core.utils.SpringContextHolder;
import com.byyy.ccts.core.utils.StringUtils;
import com.byyy.ccts.modules.cc.Global;
import com.byyy.ccts.modules.cc.entity.ccts.PsZcdHz;
import com.byyy.ccts.modules.cc.entity.ccts.PsZcdMx;
import com.byyy.ccts.modules.cc.entity.ccts.TSDeviceWarningLog;
import com.byyy.ccts.modules.cc.entity.ccts.Warning;
import com.byyy.ccts.modules.cc.mapper.DeviceWarningLogMapper;
import com.byyy.ccts.modules.cc.mapper.WarningMapper;
import com.byyy.ccts.modules.cc.service.IPsZcdMxService;
import com.byyy.ccts.modules.cc.service.IPsZcdService;
import com.byyy.ccts.modules.cc.service.IWarningService;
import com.byyy.ccts.modules.sys.entity.Dict;
import com.byyy.ccts.modules.sys.entity.Log;
import com.byyy.ccts.modules.sys.mapper.LogMapper;
import com.byyy.ccts.modules.sys.mapper.ParamMapper;
import com.byyy.ccts.modules.sys.service.IDictService;
import com.byyy.ccts.modules.sys.service.ILogService;
import com.byyy.ccts.modules.sys.service.IParamService;
import com.byyy.ccts.modules.sys.utils.UserUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by DELL on 2018-8-21.
 */
@Transactional
@Service("warningService")
public class WarningService extends CommonServiceImpl<WarningMapper, Warning> implements IWarningService, ILogBase {

    @Autowired
    private IDictService dictService;

    @Autowired
    private ILogService logService;

    @Autowired
    private IParamService paramService;

    @Autowired
    private IPsZcdService psZcdService;

    @Autowired
    private IPsZcdMxService psZcdMxService;

    @Autowired
    private LogMapper logMapper;

    @Autowired
    private ParamMapper paramSettingMapper;

    @Autowired
    private DeviceWarningLogMapper deviceWarningLogMapper;

    @Override
    public Page<Warning> warningList(Queryable queryable, Wrapper<Warning> wrapper) {
        QueryToWrapper<Warning> queryToWrapper = new QueryToWrapper<>();
        queryToWrapper.parseCondition(wrapper, queryable);
        // 排序问题
        queryToWrapper.parseSort(wrapper, queryable);
        Pageable pageable = queryable.getPageable();
        com.baomidou.mybatisplus.plugins.Page<Warning> page = new com.baomidou.mybatisplus.plugins.Page<Warning>(
                pageable.getPageNumber(), pageable.getPageSize());
        com.baomidou.mybatisplus.plugins.Page<Warning> content = warningListPage(page, wrapper);
        return new PageImpl<Warning>(content.getRecords(), queryable.getPageable(), content.getTotal());
    }

    @Override
    public com.baomidou.mybatisplus.plugins.Page<Warning> warningListPage(com.baomidou.mybatisplus.plugins.Page<Warning> page, Wrapper<Warning> wrapper) {
        page.setRecords(baseMapper.selectWarningPage(page, wrapper));
        return page;
    }

    /**
     * 更新温度数据
     * @param warning
     */
    @Override
    public void updateTemp(Warning warning, float temperatureBefore) {
        this.baseMapper.updateHumitureWarned("T_S_HUMITURE", warning);
        this.baseMapper.updateHumitureWarned("T_S_HUMITURE_HANDLE", warning);
        this.deleteTempAlarmLog(warning);
        this.writeSysLog("更新温度数据", MessageFormat.format("设备{0}于{1}时刻的温度从{2}修改为{3}", warning.getSbNo(),
                        DateUtils.formatDate(warning.getCollectTime(), Global.PATTERN_YYYYMMMDD_HHMMSS),
                        temperatureBefore, warning.getTemperature()));
    }

    /**
     * 采集设备温度延时预警
     */
    @Override
    public void humitureDataDelayWarning() {
        // 获取报警信息
        List<Warning> lastestHumitures = this.baseMapper.queryLastestHumitureInfo();
        if (lastestHumitures == null || lastestHumitures.size() < 1) {
            return;
        }

        // 获取仓库信息
        List<Dict> dicts = this.dictService.selectDictUsedListByGCode("cangku", null);
        if (dicts == null || dicts.size() < 1) {
            return;
        }

        List<Warning> warningCangku = null;
        for (Dict temp : dicts) {
            warningCangku = lastestHumitures.stream()
                    .filter(warning -> warning.getCangku().equals(temp.getValue()))
                    .collect(Collectors.toList());

            if (warningCangku != null && warningCangku.size() > 0) {
                this.sendDataDelayWarning("mailWarningDelayData" + temp.getValue(), warningCangku);
            }
        }

    }

    @Override
    public void zcdNotClosedWarning() {
        List<PsZcdHz> psZcdHzListCangku = null;
        Wrapper<PsZcdHz> wrapper = new EntityWrapper<>();
        wrapper.eq("HZ_STATE", "2");
        wrapper.isNotNull("HZ_TYGS");

        List<PsZcdHz> psZcdHzList = this.psZcdService.selectList(wrapper);
        if (psZcdHzList == null || psZcdHzList.size() < 1) {
            return;
        }

        // 获取仓库信息,遍历发送仓库相关邮件接收人
        List<Dict> dicts = this.dictService.selectDictUsedListByGCode("cangku", null);
        if (dicts == null || dicts.size() < 1) {
            return;
        }
        for (Dict temp : dicts) {
            psZcdHzListCangku = psZcdHzList.stream()
                    .filter(zcdHz -> zcdHz.getCangku().equals(temp.getValue()))
                    .collect(Collectors.toList());

            if (psZcdHzListCangku != null && psZcdHzListCangku.size() > 0) {
                this.sendPsZcdNotClosedWarning("zcdNotClosed" + temp.getValue(), psZcdHzListCangku);
            }
        }
    }

    /**
     * 发送温度延时预警邮件
     * @param code
     * @param lastestHumitures
     */
    private void sendDataDelayWarning(String code, List<Warning> lastestHumitures) {
        // 获取采集设备延时预警间隔[默认为10]
        int delayInterval = 10;
        try {
            delayInterval = Integer.valueOf(this.paramService.getValueByCode("DELAYINTERVAL"));
        }
        catch (Exception e) {
        }

        // 生成发送邮件内容
        StringBuilder content = new StringBuilder();
        for (Warning temp : lastestHumitures) {
            if (DateUtils.pastMinutes(temp.getCollectTime()) > delayInterval) {
                content.append(MessageFormat.format("装车单{0}内采集设备{1}数据获取延迟，最新时间为{2};</br>",
                        temp.getMxZhuangcdNo(), temp.getSbNo(),
                        DateUtils.formatDate(temp.getCollectTime(), Global.PATTERN_YYYYMMMDD_HHMMSS)));
            }
        }
        if (StringUtils.isEmpty(content.toString())) {
            return;
        }

        OAProducer oAProducer = (OAProducer) SpringContextHolder.getBean("oAProducer");
        oAProducer.sendOAMail(code, "数据延时预警信息", content.toString());
        // 写日志
        this.writeDeviceWaringLog(Log.TEMPERATURE_DELAY, lastestHumitures);
    }

    /**
     * 发送装车单未关闭邮件提醒
     * @param code
     * @param psZcdHzList
     */
    private void sendPsZcdNotClosedWarning(String code, List<PsZcdHz> psZcdHzList) {
        if (psZcdHzList == null || psZcdHzList.size() < 1) {
            return;
        }

        // 查询每个装车单的配送地址，多个地址;拼接
        List<String> zcdNos = new ArrayList<>();
        psZcdHzList.stream().forEach(zcdHz -> zcdNos.add(zcdHz.getZhuangcdNo()));
        Wrapper wrapper = new EntityWrapper();
        wrapper.in("MX_ZHUANGCD_NO", zcdNos);
        List<PsZcdMx> psZcdMxList = this.psZcdMxService.selectList(wrapper);

        // 将查询的装车单和配送地址装配进Map中
        Map<String, String> zcdAddrMap = new HashedMap();
        String address = null;
        String pattern = "[市区县路]";
        for (PsZcdMx temp : psZcdMxList) {
            if (!zcdAddrMap.containsKey(temp.getZhuangcdNo())) {
                address = temp.getAddress().split(pattern)[0];
                zcdAddrMap.put(temp.getZhuangcdNo(), address);
            }
            else {
                address = temp.getAddress().split(pattern)[0];
                if (zcdAddrMap.get(temp.getZhuangcdNo()).indexOf(address) < 0) {
                    zcdAddrMap.put(temp.getZhuangcdNo(), zcdAddrMap.get(temp.getZhuangcdNo()) + ";" + address);
                }
            }
        }

        // 遍历生成邮件内容主体
        StringBuilder sb = new StringBuilder("以下装车单尚未结束，请确认！<br/>");
        for (PsZcdHz temp : psZcdHzList) {
            sb.append("装车单:").append(temp.getZhuangcdNo())
                    .append("<br/>司机:").append(temp.getSiji())
                    .append("<br/>车牌号:").append(temp.getChepaiNo())
                    .append("<br/>发车时间:").append(DateUtils.formatDate(temp.getFacTime(), Global.PATTERN_YYYYMMMDD_HHMMSS))
                    .append("<br/>收货地址:").append(zcdAddrMap.get(temp.getZhuangcdNo()))
                    .append("<br/>-------------------------------------------------------------------<br/>");
        }

        OAProducer oAProducer = (OAProducer) SpringContextHolder.getBean("oAProducer");
        oAProducer.sendOAMail(code, "装车单未关闭提醒", sb.toString());
        // 写日志
        this.writeZcdNotCloseLog(Log.ZCD_NOT_CLOSE, psZcdHzList);
    }

    /**
     * 设备预警报警记录
     * @param type
     */
    private void writeDeviceWaringLog(String type, List<Warning> warningList) {
        TSDeviceWarningLog log = null;
        for (Warning temp : warningList) {
            log = new TSDeviceWarningLog();
            log.setDeviceId(temp.getSbNo());
            log.setType(type);
            log.setTitle(temp.getMxZhuangcdNo());
            log.setCollectTime(temp.getCollectTime());
            log.setContent(DateUtils.formatDate(temp.getCollectTime(), Global.PATTERN_YYYYMMMDD_HHMMSS));
            log.setCreateBy(UserUtils.getByUserName("admin"));
            log.setCreateDate(new Timestamp(System.currentTimeMillis()));
            this.deviceWarningLogMapper.insert(log);
        }
    }

    /**
     * 设备预警报警记录
     * @param type
     */
    private void writeZcdNotCloseLog(String type, List<PsZcdHz> zcdHzList) {
        TSDeviceWarningLog log = null;
        for (PsZcdHz temp : zcdHzList) {
            log = new TSDeviceWarningLog();
            log.setDeviceId(temp.getZhuangcdNo());
            log.setType(type);
            log.setTitle(temp.getZhuangcdNo());
            log.setCreateBy(UserUtils.getUser());
            log.setCreateDate(new Timestamp(System.currentTimeMillis()));
            this.deviceWarningLogMapper.insert(log);
        }
    }

    /**
     * 删除日志中对应温度预警报警记录
     * @param warning
     */
    private void deleteTempAlarmLog(Warning warning) {
        // 删除报警日志
        TSDeviceWarningLog log = new TSDeviceWarningLog();
        log.setType(Log.TEMPERATURE_ALARM);
        log.setCollectTime(warning.getCollectTime());
        log = this.deviceWarningLogMapper.selectOne(log);
        if (log != null) {
            this.deviceWarningLogMapper.deleteById(log.getId());
        }

        // 删除预警记录
        log = new TSDeviceWarningLog();
        log.setType(Log.TEMPERATURE_WARNING);
        log.setCollectTime(warning.getCollectTime());
        log = this.deviceWarningLogMapper.selectOne(log);
        if (log != null) {
            this.deviceWarningLogMapper.deleteById(log.getId());
        }
    }

    /**
     * 系统日志表中记录邮件预警信息
     * @param content
     */
    private void writeSysLog(String title, String content) {
        Log log = new Log();
        log.setTitle(title);
        log.setContent(content);
        log.setCreateBy(UserUtils.getByUserName("admin"));
        log.setCreateDate(new Timestamp(System.currentTimeMillis()));
        this.logService.insert(log);
    }

}
